CSS - Como usar a propriedade Position

Como o browser renderiza os objetos a serem exibidos

O browser renderiza os elementos exatamente como um processador de texto faria, da esquerda para a direita, de cima para baixo .
Podemos dizer que o elemento é renderizado numa 'linha' imaginária e o próximo elemento poderá ser alinhado a esta mesma 'linha' imaginária.
Contudo sabemos que o browser exibe 'algo mais' que texto mas continua seguindo esta regra sempre.

Tenha em mente que o browser sempre 'exibe'(ou renderiza) os objetos da mesma maneira, seja ele uma simples letra A ou uma tag complexa e cheia de parâmetros.
Tudo pra o browser são como 'caixas' ou 'retangulos' que se encaixam um nos outros, na sequencia, sendo que cada um deles é 'exibido' como no desenho abaixo :

Chamamos esse 'efeito' do browser de exibir todos elementos como 'caixas' de boxing.

Um conceito fundamental que você deve conhecer é a exibição do elemento 'em linha'(inline) ou 'em bloco' (block).

Elementos 'em linha'(inline)

Os elementos 'em linha' são exibidos na sequencia e sempre um do lado do outro, na mesma 'linha'.

Abaixo exibo 2 spans com cores diferentes para mostrar como exemplo.

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.

Tem duas características dos elementos em linha que precisamos observar:

1-Não são dimensionáveis, ou seja, não adianta colocar no style width ou height porque eles sempre usarão o espaço absolutamente necessário para que o elemento seja exibido com corretamente.

Abaixo repito o exemplo acima com 2 spans com cores diferentes como exemplo mas no segundo eu coloquei no style o width e o height de 300 px. Veja como não funciona:

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.

2-Não são posicionáveis, ou seja, se quiser alinhar à esquerda, centro ou à direita não será possível.

Abaixo repito o exemplo acima com 2 spans com cores diferentes como exemplo mas no segundo eu coloquei no style o text-aligh:right. Veja como não funciona:

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.

Elementos em bloco(block)

Os elementos exibidos 'em bloco' sempre ocupam uma linha exclusivamente, ou seja, se existe algo anteriormente na linha ele será renderizado na próxima linha.
Se não existe nada na linha corrente, ele será exibido na linha atual.
Outra característica do elemento em bloco é que ele ocupa a linha até o fim.

Abaixo exibo um exemplo de 2 tags p com cores diferentes como exemplo:

Antes do p1

Dentro do p1

Depois do p1. Antes do p2

Dentro do p2

Depois do p2.

Como podemos notar havia um texto antes de cada tag p e por isso a tag p foi exibida na linha logo a seguir.
Podemos notar que a tag p ocupou a linha toda.
Podemos observar ainda que o texto depois da tag p foi exibido na linha a seguir, mesmo quando havia espaço suficiente para exibir ela na linha anterior.

Se quiser mais detalhes sobre tags em linha(inline) clique aqui ou aqui

Sobre tags exibidas 'em bloco'(block) clique aqui ou aqui

Ou ainda se deseja alterar o padrão de exibição da tag clique aqui.

Se quiser mais detalhes sobre boxing clique aqui

É importante conhecer boxing em detalhes porque às vezes os elementos se desalinham na página e a gente não sabe porque. Por exemplo, quando você diz que um item tem largura x ou altura y você está considerando as margens, paddins e outros elementos de exibição ? Boxing é fundamental.

Exibindo os elementos

Por default o browser utiliza como position padrão o Static que funciona muito bem na maioria dos casos mas algumas vezes precisamos fazer algo mais elaborado.
Importante frisar que o posicionamento static não permite manipular qualquer propriedade de posicionamento do elemento, tudo esta sob o controle do browser.

A vantagem deste posicionamento é que se você redimensionar a janela do browser o próprio browser cuida da renderização dos elementos, ou seja, você não vai ver elementos encavalando um no outro ou mesmo sendo posicionado num lugar totalmente diferente do que foi pensado numa tela maior.

A propriedade position pode assumir 4 valores diferentes: Static, Relative, Absolute e Fixed. Cada uma tem um detalhe que torna vantajosa em relação a outra mas depende do sua utilização. Para saber usar é preciso conhecer elas primeiro.
Segue abaixo a explicação para de cada uma:

CSS Position Static

Esse é o valor default de todo elemento HTML, ou seja, ele vai seguir o fluxo comum da sua página como a maneira que a lemos, de cima para baixo e da direita para esquerda.

Ex: h1 { position: static }

Neste tipo de posicionamento ele segue o padrão de elemento inline (em linha) ou elemento em bloco (block). O Inline (em linha) é exibido um seguido do outro na mesma linha e o em bloco (block) ocupa exclusivamente uma linha inteira.

Dizemos que no position:static a âncora do elemento esta no seu elemento antecessor, seja ele no mesmo nível (irmão) ou um antecessor ou container .

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.

Escolhi o elemento em linha(in line) porque é o mais simples de ver o efeito. Neste caso, nada, pois o posicionamento default é o static e é o que estamos acostumados a ver no browser.

CSS Position Relative

Como o próprio nome diz, relativo a posição que o browser normalmente exibiria o elemento.

Sendo assim, este posicionamento permite um deslocamento do elemento de sua posição original que seria atribuida automaticamente pelo browser. É um pequeno deslocamento (top, right, boottom, left que pode ser feito em relação a sua posição original

Utilizando o position Relative o elemento aceita as propriedades Top, Bottom, Left e Right para definir o quanto da posição original o elemento será deslocado.

No Position Relative a âncora é a posição onde o elemento atual seria renderizado, portanto os deslocamentos feitos pelos parâmetros Top, Bottom, Left e Right são feitos relativos a posição que o elemento ocuparia sem o position relative.

Com elas você pode alterar o posicionamento do elemento. Ex:

Os estilos foram definidos assim :
   .span1 {
      position: relative;<position: relative>
      top: 40px;
      left: 60px;
      background-color:lightcoral;
   }
   .span2 {
      top: 70px;
      left: 80px;
      background-color:Highlight;
   }

Aplicando ele nos spans ficou assim :


Como o browser exibe :

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.


Resultado: Notem que o span1 se posicionou de acordo com o left (somou 60 pixels ao left do static) e top (somou 40 pixel em relação ao top do static). E esse posicionamento (top, down, left, right) funcionou porque o posicionamento foi definido como position:relative.
Já o span2 manteve o posicionamento comum (static) e ignorou os valores do left e top.
Como eu disse antes os elementos com position static (default) não podem ser posicionados.

Dizemos que no position:static a âncora do elemento esta no seu elemento antecessor que pode ser uma tag irmã no mesmo nível ou em relação ao seu container.


CSS Position Absolute

Este posicionamento quebra o posicionamento normal do browser, ou seja, o elemento antecessor ou o container. Neste caso, a âncora do elemento antecessor fica no seu 'avô' ou seja, pai do pai.

É importante notar a hierarquia de elementos pois a aplicação de um estilo em um (pai) pode influenciar o outro (filho). Para explicar melhor veja o exemplo abaixo:

<div>
      <h1>
         <span></span>
      </h1<
   <p></p>
</div>

O elemento DIV é pai (ou container) dos elementos H1, P e 'avô' do SPAN.
Os elementos H1, P são filhos do elemento DIV e SPAN é o 'neto' do Div.
Os elementos H1 e P são irmãos por estarem no mesmo nível.
E o elemento SPAN é filho do elemento H1 e também 'neto' do elemento DIV.

Eu disse acima 'avô' ou ''neto' mas na realidade só existe pai e filho numa hierarquia muito bem definida. Fica mais didático. Portanto no elemento span você teria que procurar o pai e achando o pai teria que procurar o pai para achar o avô.

Como JavaScript consegue navegar dentro do DOM podemos procurar siblings ou parentes assim :
Podemos procurar o próximo : let nextSibling = currentNode.nextElementSibling;
ou o anterior : let prevSibling = currentNode.previousElementSibling;

Com o position absolute a âncora do elemento não fica no seu antecessor mas sim no elemento pai do antecessor.

Quando não há elemento antecessor o elemento pai de maior nível hierárquico é o body.

Então, tecnicamente falando, se eu exibir um monte de tags com position absolute elas serão escritas sempre no mesmo lugar porque estão 'mirando' no elemento pai.

Exemplo:

Antes do span1Dentro do span1Depois do Span1. Antes do span2Dentro do span2Depois do Span2.

Código:

            Antes do span1<span style="position:absolute">Dentro do span1</span>Depois do Span1.
            Antes do span2<span style="position:absolute">Dentro do span2</span>Depois do Span2.

Note que o efeito acima foi feito apenas colocando o atributo position como absolute sem nenhum parâmetro de posicionamento (top, down,left, right). Com isto o elemento foi apenas retirado do fluxo normal controlado pelo posicionamento static do browser e acabou 'encavalando' um com outro, o fluxo normal e o absolute.

Uma particularidade do position:absolute é que os elementos são exibidos 'em outro contexto', ou seja, no position static e relative seguem um 'fluxo comum' mas o absolute segue outro, digamos, um segundo fluxo ou um 'fluxo alternativo' e o espaço ocupado pelos elementos do position absolute não é contabilizado pelo fluxo normal e vice-versa.

Portanto é preciso ter cuidado ao utilizar o positon absolute pois ele deixa de fazer parte do fluxo comum do documento e o espaço destinado a ele deixa de 'contar' no documento.

É muito fácil 'encavalar' tags no documento especialmente em sites responsivos.

Definição :
   .h11 {
      position: absolute;
      top: 20px;
      left: 20px;
      outline: 1px solid #444;
   }

   .h22 { outline: 1px solid #f90; }


<p>
   <div>
      <h1 class="h11">Sou um h1 com estilo h11</h1>
      <h2 class="h22">Sou um h2 com estilo h22</h2>
   </div>
</p>

Como o browser exibe:


      

Sou um h1 com estilo h11


      

Sou um h2 com estilo h22


   

Notem que o elemento H2 foi exibido normalmente, respeitando o fluxo normal do documento, enquanto o h1 se posicionou com uma distância de 20px do topo e 20px da esquerda do elemento pai, que no caso é o body, porém fora do fluxo corrente. Se esta procurando ele ele está no topo da página, veja estilo h11.


Um detalhe importante é que você pode usar medidas negativas e posicionar os elementos em locais que antes
seriam impossíveis de serem alcançados.


Na Css colocariamos:
        .divx {
            background: #eee;
            margin: 50px;
            width: 300px;
            height: 300px;
            position: relative;
        }

        h111 {
            position: absolute;
            top: -20px;
            left: -20px;
            outline: 1px solid #444;
            background: #fff;
        }
Resultado:

      

Sou um h1 com estilo h111




CSS Position Fixed

O position fixed se comporta de maneira semelhante ao absolute, deixando de fazer parte do fluxo comum da página.

Porém a grande diferença dele é que ele passa a se referenciar ao window do seu navegador, ou seja, a área que aparece para o usuário independente de barra de rolagem.

Na Css colocaríamos :
        .divy {
            background: #f90;
            width: 300px;
            height: 500px;
            position: relative;
        }

        .h1111 {
            position: fixed;
            top: 0;
            left: 20px;
            right: 20px;
            outline: 1px solid #444;
            background: #fff;
        }

        .h2222 {
            position: fixed;
            bottom: 0;
            left: 20px;
            right: 20px;
            outline: 1px solid #444;
            background: #fff;
        }
Resultado:
      

Sou um h1 com estilo h1111



      

Sou um h2 com estilo h2222




Note que o fundo ficou um laranja por causa da div e as definições de novas cores de fundo nas tags filhas foram ignoradas.

Notem também que o elemento H2 se posicionou na parte inferior da div devido ao parametro bottom:0 e o H1 se pocionou no topo da div devido ao parâmetro top:0.

Notem que o posicionamento float funciona bem para um elemento mas para um conjunto de elementos dentro de uma div a propriedade display é mais apropriada.




Outro exemplo

Suponha que você queira uma página com um menu lateral esquerdo ocupando algo perto de 20% da página e o corpo da página ocupando 80% do restante da página. Uma dica que dou é que ela usa os conceitos deste documento...position.

A ideia é ser a mais simples possível e que ocupe toda a tela sem deixar espaços não importando o tamanho dos elementos internos.

Outro detalhe fundamental é caso a janela do browser seja redimensionado os elementos devem manter sua disposição original.

Consegue fazer ?

Caso tenha feito a sua compare com a minha. Menu lateral esquerdo
Compare seu código com o meu. Não ficou bonito mas como exemplo vale.